package online.inote.common.utils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.ValueFilter;

/**
 * <p>
 * Desc: 返回值工厂类
 * </p>
 * 
 * @author 	XQF SUI
 * @Created 2016年11月18日 下午11:30:53
 * @version 1.0
 */
public class BaseResultFactory {
	
	private static Logger logger = LoggerFactory.getLogger(ResultFactory.class);
	
	// header 常量定义//
    private static final String ENCODING_PREFIX = "encoding";
    private static final String NOCACHE_PREFIX = "no-cache";
	private static final String ENCODING_DEFAULT = "UTF-8";
    private static final boolean NOCACHE_DEFAULT = true;
    
    public static final String APPLICATION_JSON = "application/json";
	
	public static final String RESULT_KEY = "result_code";
	public static final String RESULT_MES = "result_message";
	public static final String RESULT_DATA_KEY = "result_data";

	/**
	 * <p>
	 * Desc: 创建Map
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:20:42
	 * @return
	 */
	public static Map<String, Object> createMap() {
		return new HashMap<String, Object>();
	}
	
	/**
	 * <p>
	 * Desc: 创建Map
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:20:55
	 * @param key 	key
	 * @param o		value
	 * @return
	 */
	public static Map<String, Object> createMap(String key, Object o) {
		Map<String, Object> map = createMap();
		map.put(key, o);
		
		return map;
	}
	
	/**
	 * <p>
	 * Desc: 创建Map
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:20:55
	 * @param o		value
	 * @return
	 */
	public static Map<String, Object> createMap(Object o) {
		Map<String, Object> map = createMap();
		map.put(RESULT_DATA_KEY, o);
		
		return map;
	}
	
	/**
	 * <p>
	 * Desc: 创建返回Map
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:21:21
	 * @param resultEnum	结果枚举类
	 * @return
	 */
	public static Map<String, Object> createResultMap(ResultEnum resultEnum) {
		return initParam(createMap(), resultEnum.key, resultEnum.msg);
	}
	
	/**
	 * <p>
	 * Desc: 创建返回Map
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:21:56
	 * @param resultEnum		结果枚举类
	 * @param customizedMessage	自定义消息
	 * @return
	 */
	public static Map<String, Object> createResultMap(ResultEnum resultEnum, String customizedMessage) {
		return initParam(createMap(), resultEnum.key, customizedMessage);
	}
	
	/**
	  * <p>
	  * Desc: 创建返回Map
	  * </p>
	  *
	  * @author XQF SUI
	  * @created 2018年8月26日 下午3:17:01
	  * @param resultEnum
	  * @param object
	  * @return
	 */
	public static Map<String, Object> createResultMap(ResultEnum resultEnum, Object object) {
		return createResultMap(resultEnum, createMap(object));
	}
	
	/**
	 * <p>
	 * Desc: 创建返回Map
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:23:23
	 * @param resultEnum		结果枚举类
	 * @param customizedMessage	自定义消息
	 * @param o					消息参数
	 * @return
	 */
	public static Map<String, Object> createResultMap(ResultEnum resultEnum, String customizedMessage, Object... o) {
		return initParam(createMap(), resultEnum.key, StringUtils.initMessage(customizedMessage, o));
	}
	
	/**
	 * <p>
	 * Desc: 创建返回Map
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:28:17
	 * @param customizedCode	自定义CODE
	 * @param customizedMessage	自定义消息
	 * @param paramMap			返回参数Map
	 * @return
	 */
	public static Map<String, Object> createResultMap(String customizedCode, String customizedMessage, Map<String, Object> paramMap) {
		return initParam(paramMap, customizedCode, customizedMessage);
	}
	
	/**
	 * <p>
	 * Desc: 创建返回Map
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:29:07
	 * @param resultEnum	结果枚举类
	 * @param paramMap		返回参数Map
	 * @return
	 */
	public static Map<String, Object> createResultMap(ResultEnum resultEnum, Map<String, Object> paramMap) {
		return initParam(paramMap, resultEnum.key, resultEnum.msg);
	}
	
	/**
	 * <p>
	 * Desc: 创建返回JSON
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:30:43
	 * @param customizedCode	自定义CODE
	 * @param o					返回消息
	 * @return
	 */
	public static String createResultJSON(String customizedCode, Object o) {
		return JSON.toJSONString(createMap(customizedCode, o));
	}
	
	/**
	 * <p>
	 * Desc: 创建返回JSON
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:34:06
	 * @param resultEnum	结果枚举类
	 * @return
	 */
	public static String createResultJSON(ResultEnum resultEnum) {
		return JSON.toJSONString(createResultMap(resultEnum));
	}
	
	/**
	 * <p>
	 * Desc: 创建返回JSON
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:35:53
	 * @param resultEnum		结果枚举类
	 * @param customizedMessage	自定义消息
	 * @return
	 */
	public static String createResultJSON(ResultEnum resultEnum, String customizedMessage) {
		return JSON.toJSONString(createResultMap(resultEnum, customizedMessage));
	}
	
	/**
	 * <p>
	 * Desc: 创建返回JSON
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:36:19
	 * @param resultEnum		结果枚举类
	 * @param customizedMessage	自定义消息
	 * @param o					消息参数
	 * @return
	 */
	public static String createResultJSON(ResultEnum resultEnum, String customizedMessage, Object... o) {
		return JSON.toJSONString(createResultMap(resultEnum, StringUtils.initMessage(customizedMessage, o)));
	}
	
	/**
	 * <p>
	 * Desc: 创建返回JSON
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:38:01
	 * @param resultEnum	结果枚举类
	 * @param paramMap		返回参数Map
	 * @return
	 */
	public static String createResultJSON(ResultEnum resultEnum, Map<String, Object> paramMap) {
		return JSON.toJSONString(createResultMap(resultEnum, paramMap));
	}
	
	/**
	 * <p>
	 * Desc: 创建返回JSON
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:39:13
	 * @param customizedCode	自定义CODE
	 * @param customizedMessage	自定义消息
	 * @param paramMap			返回参数Map
	 * @return
	 */
	public static String createResultJSON(String customizedCode, String customizedMessage, Map<String, Object> paramMap) {
		return JSON.toJSONString(createResultMap(customizedCode, customizedMessage, paramMap));
	}
	
	/**
	  * <p>
	  * Desc: 创建返回JSON
	  * </p>
	  *
	  * @author Sui
	  * @created 2017年12月4日 下午10:17:02
	  * @param commonSuccess
	  * @param page
	  * @return
	  */
	public static String createResultJSON(ResultEnum resultEnum, Object o) {
		return createResultJSON(resultEnum, createMap(o));
	}
	
	/**
	 * <p>
	 * Desc: 初始化参数
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:41:40
	 * @param paramMap
	 * @param code
	 * @param message
	 * @return
	 */
	public static Map<String, Object> initParam(Map<String, Object> paramMap, String code, String message) {
		paramMap.put(RESULT_KEY, code);
		paramMap.put(RESULT_MES, message);
		
		return paramMap;
	}
	
	/**
	 * <p>
	 * Desc: 结果枚举类(可根据需求考虑单独出去)
	 * </p>
	 * 
	 * @author 	XQF SUI
	 * @Created 2016年11月19日 下午3:42:09
	 * @version 1.0
	 */
	public enum ResultEnum {
		
		/**
		 * 成功(A10001)
		 */
		SUCCESS("A10001", "成功"),
		
		/**
		 * 失败(A10002)
		 */
		FAIL("A10002", "失败"),
		
		/**
		 * 已存在(A10003)
		 */
		EXISTS("A10003", "已存在"),
		
		/**
		 * 不存在(A10004)
		 */
		NON_EXISTS("A10004", "不存在");
		
		private String key;
		private String msg;
		
		ResultEnum(String key, String msg) {
			this.key = key;
			this.msg = msg;
		}
	}
	
	/**
	 * <p>
	 * Desc: 向前端写信息
	 * </p>
	 *
	 * @author Sui
	 * @created 2018年1月23日 下午11:37:41
	 * @param response
	 * @param o
	 */
	public static void writeJSON(HttpServletResponse response, Object o) {
		writeJSON(response, o, null);
	}
	
	/**
	 * <p>
	 * Desc: 向前端写信息
	 * </p>
	 *
	 * @author Sui
	 * @created 2018年1月23日 下午11:37:41
	 * @param response
	 * @param o
	 */
	public static void writeJSON(HttpServletResponse response, Object o, ValueFilter filter) {
		if (filter == null) {
			writeJSON(response, JSON.toJSONString(o));
		} else {
			writeJSON(response, JSON.toJSONString(o, filter));
		}
	}
	
	/**
	 * <p>
	 * Desc: 向前端写信息
	 * </p>
	 *
	 * @author Sui
	 * @created 2018年1月23日 下午11:32:18
	 * @param response
	 * @param content
	 */
	public static void writeJSON(HttpServletResponse response, final String content) {
		writeJSON(response, APPLICATION_JSON, content, ENCODING_PREFIX + ":" + ENCODING_DEFAULT);
	}
	
	/**
	 * <p>
	 * Desc: 向前端写向信息
	 * </p>
	 *
	 * @author Sui
	 * @created 2018年1月23日 下午11:26:18
	 * @param response
	 * @param contentType 内容类型
	 * @param content 内容
	 * @param headers 
	 */
	public static void writeJSON(HttpServletResponse response, final String contentType, final String content, final String... headers) {
		logger.debug("返回前端信息...");
		try {
            // 分析headers参数
            String encoding = ENCODING_DEFAULT;
            boolean noCache = NOCACHE_DEFAULT;
            
            for (String header : headers) {
                String headerName = StringUtils.substringBefore(header, ":");
                String headerValue = StringUtils.substringAfter(header, ":");

                if (StringUtils.equalsIgnoreCase(headerName, ENCODING_PREFIX)) {
                    encoding = headerValue;
                } else if (StringUtils.equalsIgnoreCase(headerName, NOCACHE_PREFIX)) {
                    noCache = Boolean.parseBoolean(headerValue);
                } else {
                    throw new IllegalArgumentException(headerName + "不是一个合法的header类型");
                }
            }

            // 设置headers参数
            String fullContentType = contentType + ";charset=" + encoding;
            response.setContentType(fullContentType);
            
            logger.debug("fullContentType:[ {} ], noCache:[ {} ]", fullContentType, noCache);
            
            if (noCache) {
                response.setHeader("Pragma", "No-cache");
                response.setHeader("Cache-Control", "no-cache");
                response.setDateHeader("Expires", 0);
            }

            response.getWriter().write(content);
            response.getWriter().flush();
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
	}
	
	/**
	 * <p>
	 * Desc: 测试Main方法
	 * </p>
	 * 
	 * @author XQF SUI
	 * @date 2016年11月19日 下午3:46:49
	 * @param args
	 */
	public static void main(String[] args) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("date", "test");
		
		System.out.println(createResultJSON(ResultEnum.FAIL));
	}
}